# A multiple interval geom (vertical)
#
# Author: mjskay
###############################################################################


# Names that should be suppressed from global variable check by codetools
# Names used broadly should be put in _global_variables.R
globalVariables(c(".lower", ".upper", ".width"))


#' Multiple uncertainty interval plots (ggplot geom)
#'
#' Multiple interval geoms with default aesthetics
#' designed for use with output from [point_interval()].
#' Wrapper around [geom_slabinterval()].
#'
#' These geoms are wrappers around [geom_slabinterval()] with defaults designed to produce
#' multiple interval plots. These geoms set some default aesthetics equal
#' to the `.lower`, `.upper`, and `.width` columns generated by the `point_interval` family
#' of functions, making them often more convenient than vanilla [geom_linerange()]
#' when used with functions like [median_qi()], [mean_qi()],
#' [mode_hdi()], etc.
#'
#' Specifically, `geom_interval` acts as if its default aesthetics are
#' `aes(color = fct_rev(ordered(.width)))`.
#'
#' @eval rd_slabinterval_aesthetics(geom = GeomInterval, geom_name = "geom_interval")
#' @inheritParams geom_slabinterval
#' @inheritDotParams geom_slabinterval
#' @param position The position adjustment to use for overlapping points on this layer. Setting this equal to
#' `"dodge"` can be useful if you have overlapping intervals.
#' @return A [ggplot2::Geom] representing a multiple interval geometry which can
#' be added to a [ggplot()] object.
#' @author Matthew Kay
#' @seealso See [stat_interval()] for the stat version, intended
#' for use on samples from a distribution.
#' See [geom_interval()] for a similar geom intended for intervals without
#' point summaries.
#' See [stat_sample_slabinterval()] for a variety of other
#' stats that combine intervals with densities and CDFs.
#' See [geom_slabinterval()] for the geom that these geoms wrap. All parameters of that geom are
#' available to these geoms.
#' @examples
#'
#' library(dplyr)
#' library(ggplot2)
#'
#' theme_set(theme_ggdist())
#'
#' data(RankCorr_u_tau, package = "ggdist")
#'
#' # orientation is detected automatically based on
#' # use of xmin/xmax or ymin/ymax
#'
#' RankCorr_u_tau %>%
#'   group_by(i) %>%
#'   median_qi(.width = c(.5, .8, .95, .99)) %>%
#'   ggplot(aes(y = i, x = u_tau, xmin = .lower, xmax = .upper)) +
#'   geom_interval() +
#'   scale_color_brewer()
#'
#' RankCorr_u_tau %>%
#'   group_by(i) %>%
#'   median_qi(.width = c(.5, .8, .95, .99)) %>%
#'   ggplot(aes(x = i, y = u_tau, ymin = .lower, ymax = .upper)) +
#'   geom_interval() +
#'   scale_color_brewer()
#'
#' @import ggplot2
#' @export
geom_interval = function(
  mapping = NULL,
  data = NULL,
  stat = "identity",
  position = "identity",
  ...,

  side = "both",
  orientation = NA,
  interval_size_range = c(1, 6),
  show_slab = FALSE,
  show_point = FALSE
) {

  layer_geom_slabinterval(
    data = data,
    mapping = mapping,
    default_mapping = aes(color = forcats::fct_rev(ordered(.width))),
    stat = stat,
    geom = GeomInterval,
    position = position,
    ...,

    side = side,
    orientation = orientation,
    interval_size_range = interval_size_range,
    show_slab = show_slab,
    show_point = show_point,

    datatype = "interval"
  )
}

#' @rdname ggdist-ggproto
#' @format NULL
#' @usage NULL
#' @import ggplot2
#' @export
GeomInterval = ggproto("GeomInterval", GeomSlabinterval,
  default_key_aes = defaults(aes(
    datatype = "interval"
  ), GeomSlabinterval$default_aes),

  default_key_aes = defaults(aes(
    size = 4,
    fill = NA
  ), GeomSlabinterval$default_key_aes),

  default_params = defaults(list(
    side = "both",
    orientation = NA,
    interval_size_range = c(1, 6),
    show_slab = FALSE,
    show_point = FALSE
  ), GeomSlabinterval$default_params),

  default_datatype = "interval"
)
